package project02;

/**
 * Title: Project2Window class for CSIS 235 Project 2
 * Description: CS 235 Project #2 - Part 2
 *              Basic GUI program used to ask the user for age values and
 *              compute and print the average.
 *              This class is a "server" class used by the main class.
 *              This is where all the graphical user interface is implemented.
 * Modifications: 
 *   Name     Description
 * 
 * @author Anthony Varghese
 * @email  anthony.varghese@uwrf.edu
 * @date   January 30th 2012
 */


import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;


public class Project2Window extends JFrame implements ActionListener {

	/**
	 * Data members
	 * - the serialVersionUID is used for serialization - something
	 *   we will get to later in the course. Setting this to  a
	 *   "default" version of 1 prevents us from getting a compiler
	 *   warning. 
	 */
	private static final long serialVersionUID = 1L;

	// Position and size of the window frame
	private static final int FRAME_TOP_LEFT_X = 200; // pixels from left edge of screen
	private static final int FRAME_TOP_LEFT_Y = 200; // pixels from top edge of screen
	private static final int FRAME_WIDTH  = 400;     // pixels wide
	private static final int FRAME_HEIGHT = 300;	  // pixels high
	
	// Components inside the Window
	private JLabel description; // Tells user what to do
	// Position and size of the description label
	private static final int LABEL_TOP_LEFT_X = 30; // pixels from left edge of window
	private static final int LABEL_TOP_LEFT_Y = 0; // pixels from top edge of window
	private static final int LABEL_WIDTH = FRAME_WIDTH - 2*30; // pixels wide
	private static final int LABEL_HEIGHT = 30;   // pixels high
	
	private JTextField ageBox; // allows user to type numbers - ages
	private static final int TEXTBOX_TOP_LEFT_X = LABEL_TOP_LEFT_X;  // as before, all pixels
	private static final int TEXTBOX_TOP_LEFT_Y = LABEL_TOP_LEFT_Y + LABEL_HEIGHT;
	private static final int TEXTBOX_WIDTH = LABEL_WIDTH / 2;
	private static final int TEXTBOX_HEIGHT = 50;
	
	private JButton enterButton; // user should use this when done typing a number 
	private static final int BUTTON_TOP_LEFT_X = TEXTBOX_TOP_LEFT_X + TEXTBOX_WIDTH + 30;
	private static final int BUTTON_TOP_LEFT_Y = TEXTBOX_TOP_LEFT_Y;
	private static final int BUTTON_WIDTH = FRAME_WIDTH - BUTTON_TOP_LEFT_X - 30;
	private static final int BUTTON_HEIGHT = 40;
	
	private JLabel average; // to display the average age
	private static final int AVERAGE_TOP_LEFT_X = TEXTBOX_TOP_LEFT_X;
	private static final int AVERAGE_TOP_LEFT_Y = TEXTBOX_TOP_LEFT_Y + TEXTBOX_HEIGHT + 50;
	private static final int AVERAGE_WIDTH = LABEL_WIDTH;
	private static final int AVERAGE_HEIGHT = 100;
	
	// Data in Components
	private static final String descriptionString = "Enter the ages below so we can compute the average.";
	private static final String descriptionAfterUse = "Press the OK button to store this value";
	private static final String descriptionBadValue = "Enter a valid integer.";
	private static final String descriptionAreYouSure = "Hmmm ... are sure about this?";
	private static final String averageStringBase = "Average age is ";
	
	// Data members used to calculate average age
	private int averageAge;
	private int count;
	
	/**
	 * Project2Window - constructor for this class
	 * @param title - a String that will appear in the title of the window
	 * 
	 */
	public Project2Window(String title) {
		super(title);
		// Position of the top-left corner of the window.
		setLocation( FRAME_TOP_LEFT_X, FRAME_TOP_LEFT_Y );
		setSize( FRAME_WIDTH, FRAME_HEIGHT );
		
		// Without the next line, the program is still running even if the window is "closed"
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		// We want to position our components - labels and buttons - ourselves. So disable
		//   any default layout managers that might try to position things
		setLayout( null );
		
		// Position Components inside the Window.
		description = new JLabel( descriptionString );
		description.setBounds( LABEL_TOP_LEFT_X, LABEL_TOP_LEFT_Y, LABEL_WIDTH, LABEL_HEIGHT );
		add( description );
		
		ageBox = new JTextField("");
		ageBox.setBounds( TEXTBOX_TOP_LEFT_X, TEXTBOX_TOP_LEFT_Y, TEXTBOX_WIDTH, TEXTBOX_HEIGHT );
		add( ageBox );
		// when the user hits the Enter key on the keyboard, an event will be generated.
		ageBox.addActionListener( this );
		ageBox.addKeyListener(
				new KeyListener(){
					public void keyPressed(KeyEvent arg0) {	} // not used
					public void keyReleased(KeyEvent arg0) {  } // not used
					public void keyTyped(KeyEvent arg0) {
						processAge();
					}
				}
		);			
		
		enterButton = new JButton("OK");
		enterButton.setBounds(BUTTON_TOP_LEFT_X, BUTTON_TOP_LEFT_Y, BUTTON_WIDTH, BUTTON_HEIGHT );
		enterButton.addActionListener(
				// Code to process button clicks is in this anonymous class that implements ActionListener 
				new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						int currentAge = processAge();
						if ( currentAge >= 0 ){
							int total = averageAge * count + currentAge;
							count++;
							averageAge = total / count;
							
							average.setText(  averageStringBase + averageAge );
						}
					}
				}
		);
		
		average = new JLabel( averageStringBase + 0 );
		average.setBounds(AVERAGE_TOP_LEFT_X, AVERAGE_TOP_LEFT_Y, AVERAGE_WIDTH, AVERAGE_HEIGHT );
		average.setFont( new Font( "Dialog", Font.PLAIN, 30 ) );
		add( average );
	}

	/**
	 * actionPerformed - method that process events generated by user input
	 *  
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent arg0) {
		Object source = arg0.getSource();
		if ( source instanceof JTextField ){
			processAge();
		}
	}

	/**
	 * processAge - this method is used to check if the current value being entered in
	 * the ageBox is a valid age value. i.e. an actual number not less than 0. 
	 */
	private int processAge(){
		String agetext = ageBox.getText();
		int age = 0;
		try {
			age = Integer.parseInt( agetext ); // invalid characters will generate an exception
			// check if age is valid.
			if (age < 0){
				description.setText( descriptionBadValue );
			} else {
				description.setText( descriptionAfterUse );
				// make the button magically appear!
				add( enterButton );
				if ( age > 100)
					description.setText( descriptionAreYouSure );
				repaint();
			}
		} catch (NumberFormatException nfe){				
			description.setText( descriptionBadValue );
		}
		
		return age;
	}
}